//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.Generic;
using OpenLS.Spreadsheet.Extensibility;

namespace OpenLS.Spreadsheet.Expressions
{
    abstract class Expression: UnqualifiedExpressionBase
    {
        public override Expression QualifiedExpression(Parsing.RangeFactory factory)
        {
            return this;
        }
        public abstract string GetText(TextContext context);
        internal string GetTextWithEqual(TextContext context)
        {
            return "=" + GetText(context);
        }
        public abstract IEnumerable<Expression> GetSubExpressions();
        /*{
            yield break;
        }*/
        public abstract IEnumerable<IDependencyNode> GetPrecedents(EvaluationContext context);

        public object GetObject(EvaluationContext context)
        {
            try
            {
                return GetObjectImp(context);
            }
            catch (ErrorException errorException)
            {
                return errorException.Error;
            }
            catch (Exception)
            {
                return Errors.ValueError;
            }
        }
        public object GetNormalizedValue(EvaluationContext context)
        {
            object value = GetValueAsTop(context);
            var result = CellHelper.NormalizedValue(value);
            if (result == null)
                return 0d;
            return result;
        }
        protected virtual object GetValueAsTop(EvaluationContext caller)
        {
            object result =  GetValue(caller);
            if (result == null)
                result = 0d;
            return result;
        }
        public virtual object GetValue(EvaluationContext caller)
        {
            object o = GetObject(caller);
            if (o is Cell)
                o = ((Cell)o).Value;
            return o;
        }
        protected abstract object GetObjectImp(EvaluationContext context);
        public abstract Expression Offset(CellRelativeAddress a);

        internal abstract Expression Transposed(Cell target);
    }
}
